package com.sm;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.statemachine.persist.StateMachinePersister;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.EnumSet;

/**
 * @Author 刘志伟
 * @create 2022/9/22 17:43
 */
@SpringBootApplication
@RestController
public class StateMachineApplication implements CommandLineRunner {

    public static final String stateMachineId = "orderStateMachine";

    @Autowired
    private StateMachineFactory<OrderStatus, OrderStatusChangeEvent> orderStateMachineFactory;

    @Autowired
    private StateMachinePersister<OrderStatus, OrderStatusChangeEvent, Order> persister;

    public static void main(String[] args) {
        SpringApplication.run(StateMachineApplication.class, args);
    }

    @RequestMapping("/test-sm")
    public String testSm() {

        return "11111";
    }
    @GetMapping("/create")
    public Order createOrder() {
        Order order = Order.builder().id(1L).name("iphone14").status(OrderStatus.WAIT_PAYMENT).build();
        return order;
    }

    @RequestMapping("/pay")
    public Boolean pay() {
        Order order = Order.builder().id(1L).name("iphone14").status(OrderStatus.WAIT_PAYMENT).build();
        System.out.println(" 等待支付 -> 等待发货");
        Message message = MessageBuilder.withPayload(OrderStatusChangeEvent.PAYED).setHeader("order", order).build();
        if (!sendEvent(message, order)) {
            System.out.println("支付异常后，订单状态为："+order.getStatus());
        } else {
            System.out.println("支付成功后，订单状态为："+order.getStatus());
        }
        return true;
    }


    /**
     * 发送订单状态转换事件
     *
     * @param message
     * @param order
     * @return
     */
    private boolean sendEvent(Message<OrderStatusChangeEvent> message, Order order) {
        synchronized (String.valueOf(order.getId()).intern()) {
            StateMachine<OrderStatus, OrderStatusChangeEvent> orderStateMachine =
                    orderStateMachineFactory.getStateMachine(stateMachineId);
            System.out.println("id=" + order.getId() + " 状态机 orderStateMachine" + orderStateMachine);
            boolean result = false;
            try {
                orderStateMachine.start();
                //尝试恢复状态机状态
                persister.restore(orderStateMachine, order);
                System.out.println("id=" + order.getId() + " 状态机 orderStateMachine id=" + orderStateMachine.getId());
                //添加延迟用于线程安全测试
                Thread.sleep(1000);
                result = orderStateMachine.sendEvent(message);
                //持久化状态机状态
                persister.persist(orderStateMachine, order);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                orderStateMachine.stop();
            }
            return result;
        }
    }

    @Override
    public void run(String... args) throws Exception {

    }
}
